﻿#include "dxstdafx.h"
#include "LandedTitlesIO.h"
#include "Support/AnalyseTree/AnalyseTreeExtra.h"

#define POINTERTRANSFORM(C)\
	C* cp = nullptr;\
	if (L"layer" == m_list_StartObjKey.back()) { _st_layer* p_layer = static_cast<_st_layer*>(m_list_OperatorPtr.back()); CHECK_RETURN(p_layer); cp = (C*)(p_layer); }\
	else if (L"pagan_coa" == m_list_StartObjKey.back()) { _st_pagan_coa* p_pagan_coa = static_cast<_st_pagan_coa*>(m_list_OperatorPtr.back()); CHECK_RETURN(p_pagan_coa); cp = (C*)(p_pagan_coa); }\
	else if (L"coat_of_arms" == m_list_StartObjKey.back()) { _st_coat_of_arms* p_coat_of_arms = static_cast<_st_coat_of_arms*>(m_list_OperatorPtr.back()); CHECK_RETURN(p_coat_of_arms); cp = (C*)(p_coat_of_arms); }\
	else { _stLandedTitlesProperty* pLTP = static_cast<_stLandedTitlesProperty*>(m_list_OperatorPtr.back()); CHECK_RETURN(pLTP); cp = (C*)(pLTP); }\
	CHECK_RETURN(cp);\

// 需要特殊处理逐级指针转换
// 插入嵌套结构struct 
#define NESTED_STRCUCT_INSERT(C, P)\
[this](const void* vp){\
	if (m_list_OperatorPtr.empty()) return;\
	if (m_list_StartObjKey.empty()) return;\
	C* cp = nullptr;\
	if (L"layer" == m_list_StartObjKey.back()) { _stLandedTitlesProperty* pLTP = static_cast<_stLandedTitlesProperty*>(m_list_OperatorPtr.back()); CHECK_RETURN(pLTP); cp = (C*)(pLTP); }\
	else { cp = static_cast<C*>(m_list_OperatorPtr.back()); }\
	CHECK_RETURN(cp);\
	m_list_OperatorPtr.push_back(&cp->P); }\

// (C*)(m_list_OperatorPtr.back())->P = (*T)(vp)  普通赋值操作
#define NORMAL_ASSIGN(C, P, T)\
[this](const void* vp){	CHECK_RETURN(vp);\
	if (m_list_OperatorPtr.empty()) return;\
	if (m_list_StartObjKey.empty()) return;\
	POINTERTRANSFORM(C)\
	const T* tp = static_cast<const T*>(vp);\
	CHECK_RETURN(tp);\
	cp->P = *tp; }\

// (C*)(m_list_OperatorPtr.back())->P.push_back((*T)(vp))  push_back赋值操作
#define PUSHBACK_ASSIGN(C, P, T)\
[this](const void* vp){ CHECK_RETURN(vp);\
	if (m_list_OperatorPtr.empty()) return;\
	if (m_list_StartObjKey.empty()) return;\
	POINTERTRANSFORM(C)\
	const T* tp = static_cast<const T*>(vp);\
	CHECK_RETURN(tp);\
	cp->P.push_back(*tp); }\

CLandedTitlesReaderHandle::CLandedTitlesReaderHandle(std::unordered_map<std::wstring, _stLandedTitlesProperty>* map)
	: BaseReaderHandler(map)
{
	m_map_OperatorFunction = {
		// bool
		{ L"rebel", NORMAL_ASSIGN(_st_rebel, m_b_rebel, bool) },
		{ L"landless", NORMAL_ASSIGN(_st_landless, m_b_landless, bool) },
		{ L"primary", NORMAL_ASSIGN(_st_primary, m_b_primary, bool) },
		{ L"tribe", NORMAL_ASSIGN(_st_tribe, m_b_tribe, bool) },
		{ L"pirate", NORMAL_ASSIGN(_st_pirate, m_b_pirate, bool) },
		{ L"location_ruler_title", NORMAL_ASSIGN(_st_location_ruler_title, m_b_location_ruler_title, bool) },
		{ L"dynasty_title_names", NORMAL_ASSIGN(_st_dynasty_title_names, m_b_dynasty_title_names, bool) },
		{ L"caliphate", NORMAL_ASSIGN(_st_caliphate, m_b_caliphate, bool) },
		{ L"mercenary", NORMAL_ASSIGN(_st_mercenary, m_b_mercenary, bool) },
		{ L"independent", NORMAL_ASSIGN(_st_independent, m_b_independent, bool) },
		{ L"pentarchy", NORMAL_ASSIGN(_st_pentarchy, m_b_pentarchy, bool) },
		{ L"used_for_dynasty_names", NORMAL_ASSIGN(_st_used_for_dynasty_names, m_b_used_for_dynasty_names, bool) },
		{ L"creation_requires_capital", NORMAL_ASSIGN(_st_creation_requires_capital, m_b_creation_requires_capital, bool) },

		{ L"template", NORMAL_ASSIGN(_st_template, m_n_template, BYTE) },
		{ L"capital", NORMAL_ASSIGN(_st_capital, m_n_capital, UINT16) },
		{ L"dignity", NORMAL_ASSIGN(_st_dignity, m_n_dignity, UINT16) },
		{ L"strength_growth_per_century", NORMAL_ASSIGN(_st_strength_growth_per_century, m_f_strength_growth_per_century, double) },
		{ L"texture", NORMAL_ASSIGN(_st_texture, m_n_texture, BYTE) },
		{ L"texture_internal", NORMAL_ASSIGN(_st_texture_internal, m_n_texture_internal, BYTE) },
		{ L"emblem", NORMAL_ASSIGN(_st_emblem, m_n_emblem, BYTE) },
		
		{ L"culture", NORMAL_ASSIGN(_st_culture, m_wstr_culture, std::wstring) },
		{ L"title", NORMAL_ASSIGN(_st_title, m_wstr_title, std::wstring) },
		{ L"title_female", NORMAL_ASSIGN(_st_title_female, m_wstr_title_female, std::wstring) },
		{ L"foa", NORMAL_ASSIGN(_st_foa, m_wstr_foa, std::wstring) },
		{ L"short_name", NORMAL_ASSIGN(_st_short_name, m_b_short_name, bool) },
		{ L"controls_religion", NORMAL_ASSIGN(_st_controls_religion, m_wstr_controls_religion, std::wstring) },
		{ L"religion", NORMAL_ASSIGN(_st_religion, m_wstr_religion, std::wstring) },
		{ L"mercenary_type", NORMAL_ASSIGN(_st_mercenary_type, m_wstr_mercenary_type, std::wstring) },
		

		{ L"color", PUSHBACK_ASSIGN(_st_color, m_vec_color, BYTE) },
		{ L"color2", PUSHBACK_ASSIGN(_st_color2, m_vec_color2, BYTE) },
		{ L"data", PUSHBACK_ASSIGN(_st_data, m_vec_data, BYTE) },

		{ L"male_names", PUSHBACK_ASSIGN(_st_male_names, m_list_male_names, std::wstring) },
		{ L"holy_site", PUSHBACK_ASSIGN(_st_holy_site, m_list_holy_site, std::wstring) },

		{ L"catholic", NORMAL_ASSIGN(_st_catholic, m_n_catholic, int) },
		{ L"muslim", NORMAL_ASSIGN(_st_muslim, m_n_muslim, int) },
		{ L"norse_pagan_reformed", NORMAL_ASSIGN(_st_norse_pagan_reformed, m_n_norse_pagan_reformed, int) },
		{ L"baltic_pagan_reformed", NORMAL_ASSIGN(_st_baltic_pagan_reformed, m_n_baltic_pagan_reformed, int) },
		{ L"slavic_pagan_reformed", NORMAL_ASSIGN(_st_slavic_pagan_reformed, m_n_slavic_pagan_reformed, int) },
		{ L"orthodox", NORMAL_ASSIGN(_st_orthodox, m_n_orthodox, int) },
		{ L"zoroastrian_group", NORMAL_ASSIGN(_st_zoroastrian_group, m_n_zoroastrian_group, int) },
		{ L"tengri_pagan_reformed", NORMAL_ASSIGN(_st_tengri_pagan_reformed, m_n_tengri_pagan_reformed, int) },
		{ L"christian", NORMAL_ASSIGN(_st_christian, m_n_christian, int) },
		{ L"finnish_pagan_reformed", NORMAL_ASSIGN(_st_finnish_pagan_reformed, m_n_finnish_pagan_reformed, int) },
		{ L"zun_pagan_reformed", NORMAL_ASSIGN(_st_zun_pagan_reformed, m_n_zun_pagan_reformed, int) },
		{ L"west_african_pagan_reformed", NORMAL_ASSIGN(_st_west_african_pagan_reformed, m_n_west_african_pagan_reformed, int) },
		{ L"jewish_group", NORMAL_ASSIGN(_st_jewish_group, m_n_jewish_group, int) },
		
		{ L"holy_order", NORMAL_ASSIGN(_st_holy_order, m_b_holy_order, bool) },
		{ L"monthly_income", NORMAL_ASSIGN(_st_monthly_income, m_n_monthly_income, int) },
		{ L"purple_born_heirs", NORMAL_ASSIGN(_st_purple_born_heirs, m_b_purple_born_heirs, bool) },
		{ L"has_top_de_jure_capital", NORMAL_ASSIGN(_st_has_top_de_jure_capital, m_b_has_top_de_jure_capital, bool) },
		{ L"assimilate", NORMAL_ASSIGN(_st_assimilate, m_b_assimilate, bool) },
		
		{ L"layer", NESTED_STRCUCT_INSERT(_st_pagan_coa, m_st_layer) },
		{ L"coat_of_arms", NESTED_STRCUCT_INSERT(_stLandedTitlesProperty, m_st_coat_of_arms) },
		{ L"pagan_coa", NESTED_STRCUCT_INSERT(_stLandedTitlesProperty, m_st_pagan_coa) },
	};
}

bool CLandedTitlesReaderHandle::HandleBool(const std::wstring& key, bool b)
{
	if (m_bKeyInAllow || m_bKeyInGainEffect)
	{
		// 
	}
	else
	{
		return OperatorFunction(key, &b);
	}
	return true;
}

bool CLandedTitlesReaderHandle::HandleInt(const std::wstring& key, int i)
{
	if (m_bKeyInAllow || m_bKeyInGainEffect)
	{
		return true;
	}
	else
	{
		return OperatorFunction(key, &i);
	}
	return true;
}

bool CLandedTitlesReaderHandle::HandleDouble(const std::wstring& key, double d)
{
	if (m_bKeyInAllow || m_bKeyInGainEffect)
	{
		return true;
	}
	else
	{
		return OperatorFunction(key, &d);
	}
	return true;
}

bool CLandedTitlesReaderHandle::HandleString(const std::wstring& key, const std::wstring& str)
{
	if (m_bKeyInAllow || m_bKeyInGainEffect)
	{
		return true;
	}
	else
	{
		auto it_FindFunc = m_map_OperatorFunction.find(key);
		if (m_map_OperatorFunction.end() != it_FindFunc)
		{
			// 找到了 执行回调函数
			it_FindFunc->second(&str);
		}
		else
		{
			// 没找到 就是 "german" : "萨梅滕", "prussian" : "日穆德", etc.
			if (m_list_OperatorPtr.empty())
			{
				return false;
			}
			_stLandedTitlesProperty* pLTP = static_cast<_stLandedTitlesProperty*>(m_list_OperatorPtr.back());
			CHECK_RE_FALSE(pLTP);
			_st_Culture2Name* pstCulture2Name = static_cast<_st_Culture2Name*>(pLTP);
			CHECK_RE_FALSE(pstCulture2Name);
			auto iterInsert = pstCulture2Name->m_map_Culture2Name.insert(std::make_pair(key, str));
			if (!iterInsert.second)
			{
				CString strError;
				strError.Format(L"'%s' is repeat!", key.c_str());
				CommonFunc::ErrorMessageBox(strError);
				return false;
			}
		}
	}
	return true;
}

bool CLandedTitlesReaderHandle::HandleStartObj(const std::wstring& key)
{
	if (key.empty())
	{
		return BaseReaderHandler::HandleStartObj(key);
	}
	if (L"allow" == key)
	{
		m_bKeyInAllow = true;
		// 		_stLandedTitlesProperty* pstLandedTitlesProperty = static_cast<_stLandedTitlesProperty*>(m_list_OperatorPtr.back());
		// 		CHECK_RE_FALSE(pstLandedTitlesProperty);
		// 		pstLandedTitlesProperty->m_p_allow.reset();
		// 		m_list_OperatorPtr.push_back(&pstLandedTitlesProperty->m_p_allow);
	}
	else if (L"gain_effect" == key)
	{
		m_bKeyInGainEffect = true;
	}
	if (m_bKeyInAllow || m_bKeyInGainEffect)
	{
		return BaseReaderHandler::HandleStartObj(key);
// 		std::unique_ptr<AnalyseTreeNodeCondition>* pNodeCondition = static_cast<std::unique_ptr<AnalyseTreeNodeCondition>*>(m_list_OperatorPtr.back());
// 		if (L"custom_tooltip" == key)
// 		{
// 			AnalyseTreeNodeCondition* pNode = pNodeCondition->get();
// 			(*pNodeCondition)->InsertNode(std::make_unique<AnalyseTreeNodeCondition_custom_tooltip>(pNode));
// 		}
// 		else if (L"hidden_tooltip" == key)	// Creation / usurpation trigger
// 		{
// 			AnalyseTreeNodeCondition* pNode = pNodeCondition->get();
// 			(*pNodeCondition)->InsertNode(std::make_unique<AnalyseTreeNodeCondition_hidden_tooltip>(pNode));
// 		}
	}
	else
	{
		std::wstring wstrHead = key.substr(0, 2);
		if (L"e_" == wstrHead || 
			L"k_" == wstrHead ||
			L"d_" == wstrHead ||
			L"c_" == wstrHead ||
			L"b_" == wstrHead)
		{
			_stLandedTitlesProperty st_value;
			st_value.m_wstr_IndexName = key;
			if (L"e_" == wstrHead)
			{
				st_value.m_eTitleslevel = _eTitleslevel::Empire;
			}
			else if (L"k_" == wstrHead)
			{
				st_value.m_eTitleslevel = _eTitleslevel::King;
			}
			else if (L"d_" == wstrHead)
			{
				st_value.m_eTitleslevel = _eTitleslevel::Duke;
			}
			else if (L"c_" == wstrHead)
			{
				st_value.m_eTitleslevel = _eTitleslevel::Count;
			}
			else if (L"b_" == wstrHead)
			{
				st_value.m_eTitleslevel = _eTitleslevel::Baron;
			}
			
			if (m_list_StartObjKey.empty())
			{
				// 没有上级头衔
				CHECK_RE_FALSE(m_Container);
				auto iterInsertMap = m_Container->insert(std::make_pair(key, st_value));	// st_value失效
				if (!iterInsertMap.second)
				{
					CString strError;
					strError.Format(L"LandedTitles name '%s' is repeat!", key.c_str());
					CommonFunc::ErrorMessageBox(strError);
					return false;
				}
				else
				{
					m_list_OperatorPtr.push_back(&iterInsertMap.first->second);
				}
			}
			else
			{
				// 有上级头衔
				if (m_list_OperatorPtr.empty())
				{
					return false;
				}
				st_value.m_pFatherTitle = static_cast<_stLandedTitlesProperty*>(m_list_OperatorPtr.back());
				CHECK_RE_FALSE(st_value.m_pFatherTitle);

				CHECK_RE_FALSE(m_Container);
				auto iterInsertMap = m_Container->insert(std::make_pair(key, st_value));	// st_value失效
				if (!iterInsertMap.second)
				{
					CString strError;
					strError.Format(L"LandedTitles name '%s' is repeat!", key.c_str());
					CommonFunc::ErrorMessageBox(strError);
					return false;
				}

				m_list_OperatorPtr.push_back(&iterInsertMap.first->second);

				iterInsertMap.first->second.m_pFatherTitle->m_listChildTitles.push_back(&iterInsertMap.first->second);
			}
		}
		else
		{
			auto it_FindFunc = m_map_OperatorFunction.find(key);
			if (m_map_OperatorFunction.end() != it_FindFunc)
			{
				// 找到了 先把Key加入m_list_StartObjKey 用以回调函数调用
				BaseReaderHandler::HandleStartObj(key);
				// 执行回调函数
				it_FindFunc->second(nullptr);

				return true;
			}
			else
			{
				// 没找到
				CString strError;
				strError.Format(L"'%s' is not exist!", key.c_str());
				CommonFunc::ErrorMessageBox(strError);
				return false;
			}
		}
	}
	
	return BaseReaderHandler::HandleStartObj(key);
}

bool CLandedTitlesReaderHandle::HandleEndObj()
{
	if (!m_list_StartObjKey.empty())
	{
		if (L"allow" == m_list_StartObjKey.back())
		{
			m_bKeyInAllow = false;
			return BaseReaderHandler::HandleEndObj();
			// 其他操作
		}
		else if (L"gain_effect" == m_list_StartObjKey.back())
		{
			m_bKeyInGainEffect = false;
			return BaseReaderHandler::HandleEndObj();
		}
	}
	if (m_bKeyInAllow || m_bKeyInGainEffect)
	{
		return BaseReaderHandler::HandleEndObj();
	}
	if (!m_list_OperatorPtr.empty())
	{
		m_list_OperatorPtr.pop_back();
	}
	return BaseReaderHandler::HandleEndObj();
}
